﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Threading;


namespace KD.Sms.Share
{
    public class SamplingPosGen
    {
        Random ro = new Random();
        private Hashtable _HasPos;
        /// <summary>
        /// 
        /// </summary>
        /// <param name="_xbegin"></param>
        /// <param name="_xend"></param>
        /// <param name="_ybegin"></param>
        /// <param name="_yend"></param>
        /// <param name="_xOffset">X方向偏移量</param>
        /// <param name="_yOffset">y方向偏移量</param>
        public SamplingPosGen(int _xbegin, int _xend, int _ybegin, int _yend, int _deep, int _xOffset, int _yOffset)
        {
            int _iStep = 1;
            Entity.SamplingPos _ePos;
            int _iAvgX = Math.Abs(_xend - _xbegin) / 6;
            int _iAvgY = Math.Abs(_yend - _ybegin) / 3;
            //坐标生成本身存在的【X】方向【切割偏移量】
            int _iDValueX = Math.Abs(_xend - _xbegin) % 6;
            //坐标生成本身存在的【Y】方向【切割偏移量】
            int _iDValueY = Math.Abs(_yend - _ybegin) % 3;
            _HasPos = new Hashtable();
            Random ro = new Random();

            for (int i = _xbegin + _iAvgX + _iDValueX; i <= _xend; i = i + _iAvgX)
            {

                for (int j = _ybegin + _iAvgY + _iDValueY; j <= _yend; j = j + _iAvgY)
                {
                    _ePos = new Entity.SamplingPos();
                    _ePos.BlockNumber = _iStep;

                    _ePos.XBegin = i - _iAvgX + _xOffset;
                    _ePos.XEnd = i - _xOffset;
                    _ePos.X = ro.Next(_ePos.XBegin, _ePos.XEnd);

                    _ePos.YBegin = j - _iAvgY + _yOffset;
                    _ePos.YEnd = j - _yOffset;
                    _ePos.Y = ro.Next(_ePos.YBegin, _ePos.YEnd);
                    _ePos.Z = _deep;
                    _HasPos.Add(_iStep, _ePos);
                    _iStep++;
                }

                //for (int j = _ybegin + _iAvgY + _iDValueY; j <= _yend; j = j + _iAvgY)
                //{
                //    _ePos = new Entity.SamplingPos();
                //    _ePos.BlockNumber = _iStep;

                //    _ePos.XBegin = i - _iAvgX + _xOffset;
                //    _ePos.XEnd = i - _xOffset;
                //    _ePos.X = ro.Next(_ePos.XBegin, _ePos.XEnd);

                //    _ePos.YBegin = j - _iAvgY + _yOffset;
                //    _ePos.YEnd = j - _yOffset;
                //    _ePos.Y = ro.Next(_ePos.YBegin, _ePos.YEnd);
                //    _ePos.Z = _deep;
                //    _HasPos.Add(_iStep, _ePos);
                //    _iStep++;
                //}
            }

        }

        /// <summary>
        /// 提取坐标
        /// </summary>
        /// <param name="_iIndex"></param>
        /// <returns></returns>
        public Entity.SamplingPos GetBlock(int _iIndex)
        {
            return (Entity.SamplingPos)_HasPos[_iIndex];
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="posCount"></param>
        /// <param name="type"></param>
        /// <returns></returns>
        public List<Entity.SamplingPos> MakeSamplingPos(int posCount, SamplingPosMakeType type)
        {
            if (_HasPos == null || _HasPos.Count < 1)
                return null;
            SamplingPosMakeType _type = posCount > 6 ? SamplingPosMakeType.GB_FullRand : type;
            Hashtable _hasKey = new Hashtable();
            List<int> _listPoints = new List<int>();
            List<int[]> _listChose = new List<int[]>();
            List<Entity.SamplingPos> _listPos = new List<Entity.SamplingPos>();
            int _iStep = 1;
            int _iValue = 0;
            if (_type == SamplingPosMakeType.KD_3PartRand)
            {
                int[] _arr = new int[] { 1, 2, 3, 1, 2, 3, 1, 2, 3, 1, 2, 3, 1, 2, 3, 1, 2, 3, 1, 2, 3, 1, 2, 3 };
                int[] _arr1 = new int[] { 1, 2, 3, 4, 5, 6, 1, 2, 3, 4, 5, 6, 1, 2, 3, 4, 5, 6, 1, 2, 3, 4, 5, 6, 1, 2, 3, 4, 5, 6, 1, 2, 3, 4, 5, 6, 1, 2, 3, 4, 5, 6, 1, 2, 3, 4, 5, 6, 1, 2, 3, 4, 5, 6, 1, 2, 3, 4, 5, 6, 1, 2, 3, 4, 5, 6, 1, 2, 3, 4, 5, 6, 1, 2, 3, 4, 5, 6, 1, 2, 3, 4, 5, 6, 1, 2, 3, 4, 5, 6, 1, 2, 3, 4, 5, 6, 1, 2, 3, 4, 5, 6, 1, 2, 3, 4, 5, 6, 1, 2, 3, 4, 5, 6, 1, 2, 3, 4, 5, 6, 1, 2, 3, 4, 5, 6, 1, 2, 3, 4, 5, 6, 1, 2, 3, 4, 5, 6, 1, 2, 3, 4, 5, 6 };
                int[] _arr2 = new int[] { 7, 8, 9, 10, 11, 12, 7, 8, 9, 10, 11, 12, 7, 8, 9, 10, 11, 12, 7, 8, 9, 10, 11, 12, 7, 8, 9, 10, 11, 12, 7, 8, 9, 10, 11, 12, 7, 8, 9, 10, 11, 12, 7, 8, 9, 10, 11, 12, 7, 8, 9, 10, 11, 12, 7, 8, 9, 10, 11, 12, 7, 8, 9, 10, 11, 12, 7, 8, 9, 10, 11, 12, 7, 8, 9, 10, 11, 12, 7, 8, 9, 10, 11, 12, 7, 8, 9, 10, 11, 12, 7, 8, 9, 10, 11, 12, 7, 8, 9, 10, 11, 12, 7, 8, 9, 10, 11, 12, 7, 8, 9, 10, 11, 12, 7, 8, 9, 10, 11, 12, 7, 8, 9, 10, 11, 12, 7, 8, 9, 10, 11, 12, 7, 8, 9, 10, 11, 12, 7, 8, 9, 10, 11, 12 };
                int[] _arr3 = new int[] { 13, 14, 15, 16, 17, 18, 13, 14, 15, 16, 17, 18, 13, 14, 15, 16, 17, 18, 13, 14, 15, 16, 17, 18, 13, 14, 15, 16, 17, 18, 13, 14, 15, 16, 17, 18, 13, 14, 15, 16, 17, 18, 13, 14, 15, 16, 17, 18, 13, 14, 15, 16, 17, 18, 13, 14, 15, 16, 17, 18, 13, 14, 15, 16, 17, 18, 13, 14, 15, 16, 17, 18, 13, 14, 15, 16, 17, 18, 13, 14, 15, 16, 17, 18, 13, 14, 15, 16, 17, 18, 13, 14, 15, 16, 17, 18, 13, 14, 15, 16, 17, 18, 13, 14, 15, 16, 17, 18, 13, 14, 15, 16, 17, 18, 13, 14, 15, 16, 17, 18, 13, 14, 15, 16, 17, 18, 13, 14, 15, 16, 17, 18, 13, 14, 15, 16, 17, 18, 13, 14, 15, 16, 17, 18 };
                for (int i = 0; i < 180; i++)
                {
                    if (i % 3 == 0)
                        _listChose.Add(_arr1);
                    else if (i % 3 == 1)
                        _listChose.Add(_arr2);
                    else
                        _listChose.Add(_arr2);
                }

                Hashtable _hasQueue = new Hashtable();
                List<int> _listQueue = new List<int>();
                if (posCount <= 3)
                {
                    _iStep = 1;
                    while (_iStep <= posCount)
                    {
                        _iValue = _arr[ro.Next(0, (_arr.Length - 1))];
                        if (!_hasQueue.ContainsKey(_iValue))
                        {
                            _listQueue.Add(_iValue);
                            _hasQueue.Add(_iValue, 0);
                            _iStep++;
                        }
                    }
                }
                else
                {
                    for (int i = 1; i <= posCount; i++)
                    {
                        if (i <= 3)
                            _listQueue.Add(i);
                        else
                            _listQueue.Add(_arr[ro.Next(0, (_arr.Length - 1))]);
                    }
                }
                _iStep = 1;
                while (_iStep <= posCount)
                {
                    switch (_listQueue[_iStep - 1])
                    {
                        case 1:
                            _iValue = _arr1[ro.Next(0, (_arr1.Length - 1))];
                            break;
                        case 2:
                            _iValue = _arr2[ro.Next(0, (_arr2.Length - 1))];
                            break;
                        case 3:
                            _iValue = _arr3[ro.Next(0, (_arr3.Length - 1))];
                            break;
                    }
                    if (!_hasKey.ContainsKey(_iValue))
                    {
                        _listPoints.Add(_iValue);
                        _hasKey.Add(_iValue, 0);
                        _iStep++;
                    }
                }
            }
            else
            {
                int[] _arrChose = new int[1152];
                for (int i = 1; i <= 1152; i++)
                {
                    if (i % 18 == 0)
                        _arrChose[i - 1] = 18;
                    else
                        _arrChose[i - 1] = i % 18;
                }
                _iStep = 1;
                while (_iStep <= posCount)
                {
                    _iValue = _arrChose[ro.Next(0, (_arrChose.Length - 1))];
                    if (!_hasKey.ContainsKey(_iValue))
                    {
                        _listPoints.Add(_iValue);
                        _hasKey.Add(_iValue, 0);
                        _iStep++;
                    }
                }
            }
            _listPoints.Sort();
            _listPos = new List<Entity.SamplingPos>();
            for (int i = 0; i < _listPoints.Count; i++)
            {
                _listPos.Add(GetBlock(_listPoints[i]));
            }
            return _listPos;
        }

        /// <summary>
        /// 将生成的采样点所属的采样块顺序打乱
        /// </summary>
        /// <param name="listPos"></param>
        /// <returns></returns>
        public List<Entity.SamplingPos> ToRandomPos(List<Entity.SamplingPos> listPos)
        {
            for (int i = 0; i < listPos.Count; i++)
            {
                listPos[i].Index = i;
                listPos[i].Index = new Random(DateTime.Now.Millisecond + i).Next(1, 10);
                Thread.Sleep(20);
            }

            //随机发送点位信息
            return listPos.OrderBy(m => m.Index).ToList();
        }




    }
}
